package com.agricultural.machine.monitoring;

import com.agricultural.machine.chain.SafetyManager;
import com.agricultural.machine.factory.MachineFactory;
import com.agricultural.machine.logging.LogLevel;
import com.agricultural.machine.logging.Logger;
import com.agricultural.machine.common.IMachine;
import com.agricultural.machine.user.UserSessionManager;

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.OperatingSystemMXBean;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 系统监控类
 */
public class SystemMonitor {
    private static SystemMonitor instance;
    private final Logger logger;
    private final MachineFactory machineFactory;
    private final SafetyManager safetyManager;
    private final UserSessionManager sessionManager;
    private final ScheduledExecutorService scheduler;
    private final Map<String, MachineStatus> machineStatuses;
    private final MemoryMXBean memoryMXBean;
    private final OperatingSystemMXBean osMXBean;
    private final long startTime;
    
    private SystemMonitor() {
        this.logger = Logger.getInstance();
        this.machineFactory = MachineFactory.getInstance();
        this.safetyManager = SafetyManager.getInstance();
        this.sessionManager = UserSessionManager.getInstance();
        this.scheduler = Executors.newScheduledThreadPool(2);
        this.machineStatuses = new HashMap<>();
        this.memoryMXBean = ManagementFactory.getMemoryMXBean();
        this.osMXBean = ManagementFactory.getOperatingSystemMXBean();
        this.startTime = System.currentTimeMillis();
        
        // 启动监控任务
        initializeMonitoring();
    }
    
    public static synchronized SystemMonitor getInstance() {
        if (instance == null) {
            instance = new SystemMonitor();
        }
        return instance;
    }
    
    /**
     * 初始化监控任务
     */
    private void initializeMonitoring() {
        // 每5秒检查一次机器状态
        scheduler.scheduleAtFixedRate(
                this::monitorMachines,
                5,
                5,
                TimeUnit.SECONDS);
        
        // 每30秒记录一次系统状态
        scheduler.scheduleAtFixedRate(
                this::monitorSystemResources,
                1,
                30,
                TimeUnit.SECONDS);
        
        logger.info("SystemMonitor", "系统监控已初始化");
    }
    
    /**
     * 监控机器状态
     */
    private void monitorMachines() {
        try {
            Collection<IMachine> machines = machineFactory.getAllMachines().values();
            for (IMachine machine : machines) {
                String machineId = machine.getMachineId();
                boolean isRunning = machine.isRunning();
                boolean isEmergency = machine.isEmergencyStopped();
                String position = machine.getPosition();
                String stateDesc = machine.getState().getDescription();
                
                MachineStatus status = machineStatuses.getOrDefault(machineId, new MachineStatus());
                
                // 检查状态是否变化
                if (status.isRunning != isRunning || 
                        status.isEmergencyStopped != isEmergency || 
                        !status.position.equals(position) || 
                        !status.stateDescription.equals(stateDesc)) {
                    
                    // 更新状态
                    status.isRunning = isRunning;
                    status.isEmergencyStopped = isEmergency;
                    status.position = position;
                    status.stateDescription = stateDesc;
                    
                    // 保存状态
                    machineStatuses.put(machineId, status);
                    
                    // 记录状态变化
                    logger.debug("SystemMonitor", "农机 [" + machineId + "] 状态变化: " + 
                                "运行状态=" + isRunning + ", 紧急停止=" + isEmergency + 
                                ", 位置=" + position + ", 状态=" + stateDesc);
                }
            }
        } catch (Exception e) {
            logger.exception("SystemMonitor", e);
        }
    }
    
    /**
     * 监控系统资源
     */
    private void monitorSystemResources() {
        try {
            // 内存使用情况
            long totalMemory = Runtime.getRuntime().totalMemory() / (1024 * 1024);
            long freeMemory = Runtime.getRuntime().freeMemory() / (1024 * 1024);
            long usedMemory = totalMemory - freeMemory;
            
            // JVM 堆内存情况
            long heapUsed = memoryMXBean.getHeapMemoryUsage().getUsed() / (1024 * 1024);
            
            // CPU 负载
            double systemLoad = osMXBean.getSystemLoadAverage();
            
            // 系统运行时间
            long uptime = (System.currentTimeMillis() - startTime) / 1000;
            
            // 活跃会话数
            int activeSessions = sessionManager.getActiveSessionCount();
            
            // 安全事件数量
            int totalEvents = safetyManager.getEventHistory().size();
            int unhandledEvents = safetyManager.getUnhandledEvents().size();
            
            logger.debug("SystemMonitor", String.format(
                    "系统状态: 总内存=%d MB, 已用内存=%d MB, 堆内存=%d MB, " +
                    "CPU负载=%.2f, 运行时间=%d 秒, 活跃会话=%d, 安全事件=%d/%d",
                    totalMemory, usedMemory, heapUsed, systemLoad, uptime, 
                    activeSessions, unhandledEvents, totalEvents));
        } catch (Exception e) {
            logger.exception("SystemMonitor", e);
        }
    }
    
    /**
     * 获取系统运行时间（秒）
     */
    public long getUptime() {
        return (System.currentTimeMillis() - startTime) / 1000;
    }
    
    /**
     * 获取机器状态
     */
    public Map<String, MachineStatus> getMachineStatuses() {
        return new HashMap<>(machineStatuses);
    }
    
    /**
     * 关闭监控系统
     */
    public void shutdown() {
        scheduler.shutdown();
        try {
            if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) {
                scheduler.shutdownNow();
            }
        } catch (InterruptedException e) {
            scheduler.shutdownNow();
            Thread.currentThread().interrupt();
        }
        logger.info("SystemMonitor", "系统监控已关闭");
    }
    
    /**
     * 机器状态内部类
     */
    public static class MachineStatus {
        boolean isRunning = false;
        boolean isEmergencyStopped = false;
        String position = "未知";
        String stateDescription = "未知";
        
        @Override
        public String toString() {
            return "运行状态=" + isRunning + 
                   ", 紧急停止=" + isEmergencyStopped + 
                   ", 位置=" + position + 
                   ", 状态=" + stateDescription;
        }
    }
}




































